package team.seekers.catering.order.service;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import team.seekers.catering.common.enums.*;
import team.seekers.catering.common.utils.message.MessageUtils;
import team.seekers.catering.food.entity.dao.Product;
import team.seekers.catering.food.entity.vo.info.ProductInfoVO;
import team.seekers.catering.food.service.ComboService;
import team.seekers.catering.food.service.FoodService;
import team.seekers.catering.food.entity.pojo.ContainLabelListDO;
import team.seekers.catering.food.service.ProductService;
import team.seekers.catering.order.entity.vo.list.OrderListVO;
import team.seekers.catering.order.entity.dao.Order;
import team.seekers.catering.order.entity.vo.list.OrderTimeListVO;
import team.seekers.catering.order.mapper.OrderMapper;
import team.seekers.catering.config.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import team.seekers.catering.user.service.UserService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author hbc
 * @since 2022-02-28
 */
@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> {

    @Autowired
    private ConfigService configService;

    @Autowired
    private ComboService comboService;

    @Autowired
    private UserService userService;

    @Autowired
    private ProductService productService;

    @Autowired
    private FoodService foodService;

    /**
     * 根据时间段查询对应订单的信息
     */
    public List<OrderListVO> getByTime(TimeTypeEnum typeEnum) {
        ArrayList<OrderListVO> orderListVOS = new ArrayList<>();
        List<Order> list = lambdaQuery().eq(Order::getStatus,0).eq(Order::getTimeType,typeEnum).eq(Order::getIsPay,OrderTypeEnum.FINISH_ORDER).list();
        if(list != null && list.size() != 0){
            for (int i = 0; i < list.size(); i++) {
                for(int j=0;j<list.size()-1;j++){
                    String[] splitI = list.get(i).getShowId().split("-");
                    String intI = splitI[1].substring(1);
                    String[] splitJ = list.get(j).getShowId().split("-");
                    String intJ = splitJ[1].substring(1);
                    if(Integer.parseInt(intI)<Integer.parseInt(intJ)){
                        Order r=list.get(i);
                        list.set(i, list.get(j));
                        list.set(j, r);
                    }
                }
            }
        }
        for (Order order : list) {
            OrderListVO orderListVO = new OrderListVO();
            BeanUtils.copyProperties(order,orderListVO);
            Product product = productService.getById(order.getProductId());
            if (product ==null)
                break;
            orderListVO.setProductName(product.getName());
            orderListVO.setStatus(order.getStatus().getStatus());
            orderListVO.setAmount(FoodAmountTypeEnum.getByType(order.getAmount()).getAmount());
            orderListVO.setTimeType(order.getTimeType().getTime());
            orderListVO.setIsPay(order.getIsPay().getStatus());
            orderListVO.setIsPack(order.getIsPack().getType());

            if(order.getLabel() != null){
                List<ContainLabelListDO> label = JSON.parseArray(order.getLabel(), ContainLabelListDO.class);
                ArrayList<String> labelStrings = new ArrayList<>();
                for (ContainLabelListDO containLabelListDO : label) {
                    if(containLabelListDO.getIsAlone()){
                        Map<String, Boolean> chooses = containLabelListDO.getChooses();
                        for(String key:chooses.keySet()) {
                            if(chooses.get(key)){
                                labelStrings.add(containLabelListDO.getName() + " : " +key);
                            }
                        }
                    }else {
                        String keys = "";
                        Map<String, Boolean> chooses = containLabelListDO.getChooses();
                        for(String key:chooses.keySet()) {
                            if(chooses.get(key)){
                                keys = keys + " " +key;
                            }
                        }
                        labelStrings.add(containLabelListDO.getName() + " : " +keys);
                    }
                }
                orderListVO.setLabel(labelStrings);
            }
            orderListVOS.add(orderListVO);
        }
        return orderListVOS;
    }


    /**
     * 根据当前时间
     * 查看当前时间段和下一时间段的订单信息
     * @return
     * @throws ParseException
     */
    public List<OrderTimeListVO> nowOrders() throws ParseException {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd");
        Date now = new Date();
        String nowDate = dateformat1.format(now);
        String strAM = nowDate+" 11:20:00";
        Date AM = dateformat.parse(strAM);
        String strPM = nowDate+" 17:10:00";
        Date PM = dateformat.parse(strPM);
        String div = nowDate+ConfigTypeEnum.TIME_DIVISION.getName();
        Date divTime = dateformat.parse(div);
        if (now.before(divTime)){
            long l = now.getTime() - AM.getTime();
            Integer flag = Math.toIntExact(l / 600000);
            if(flag<TimeTypeEnum.ELEVEN_TWENTY_THIRTY.getType()){
                return null;
            }
            Integer flag1 = flag + 1;
            List<OrderTimeListVO> orderTimeListVOS = new ArrayList<>();
            if(flag<=TimeTypeEnum.TWELVE_THIRTY_FORTY.getType()&&flag>=TimeTypeEnum.ELEVEN_TWENTY_THIRTY.getType()){
                OrderTimeListVO orderTimeListVO = new OrderTimeListVO();
                orderTimeListVO.setTimeType(TimeTypeEnum.getByType(flag).getTime());
                orderTimeListVO.setOrderListVOS(getByTime(TimeTypeEnum.getByType(flag)));
                orderTimeListVOS.add(orderTimeListVO);
            }
            if(flag<7){
                OrderTimeListVO orderTimeListVO1 = new OrderTimeListVO();
                orderTimeListVO1.setTimeType(TimeTypeEnum.getByType(flag1).getTime());
                orderTimeListVO1.setOrderListVOS(getByTime(TimeTypeEnum.getByType(flag1)));
                orderTimeListVOS.add(orderTimeListVO1);
            }

            return orderTimeListVOS;
        }else{
            long l = now.getTime() - PM.getTime();
            Integer flag = Math.toIntExact(l / 600000) + TimeTypeEnum.SEVENTEEN_TEN_TWENTY.getType();
            if(flag<TimeTypeEnum.SEVENTEEN_TEN_TWENTY.getType()){
                return null;
            }
            Integer flag1 = flag + 1;
            List<OrderTimeListVO> orderTimeListVOS = new ArrayList<>();
            if(flag>=TimeTypeEnum.SEVENTEEN_TEN_TWENTY.getType()&&flag<=TimeTypeEnum.EIGHTEEN_TWENTY_THIRTY.getType()){
                OrderTimeListVO orderTimeListVO = new OrderTimeListVO();
                orderTimeListVO.setTimeType(TimeTypeEnum.getByType(flag).getTime());
                orderTimeListVO.setOrderListVOS(getByTime(TimeTypeEnum.getByType(flag)));
                orderTimeListVOS.add(orderTimeListVO);
            }
            if(flag<15){
                OrderTimeListVO orderTimeListVO1 = new OrderTimeListVO();
                orderTimeListVO1.setTimeType(TimeTypeEnum.getByType(flag1).getTime());
                orderTimeListVO1.setOrderListVOS(getByTime(TimeTypeEnum.getByType(flag1)));
                orderTimeListVOS.add(orderTimeListVO1);
            }

            return orderTimeListVOS;
        }
    }


    /**
     * 查看所有时间段的订单信息
     * @return
     */
    public List<OrderTimeListVO> allTimeOrders(){
        List<OrderTimeListVO> orderTimeListVOS = new ArrayList<>();
        // 获取今日零点到当前时间点
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date zero = new Date(calendar.getTimeInMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 24);
        Date last = new Date(calendar.getTimeInMillis());

        for(int type=TimeTypeEnum.ELEVEN_TWENTY_THIRTY.getType();type<=TimeTypeEnum.EIGHTEEN_TWENTY_THIRTY.getType();type++){
            List<Order> list = lambdaQuery().between(Order::getGmtCreate,zero,last).eq(Order::getIsPay,OrderTypeEnum.FINISH_ORDER).eq(Order::getTimeType, TimeTypeEnum.getByType(type)).list();
            if(list!=null){
                for (int i = 0; i < list.size(); i++) {
                    for(int j=0;j<list.size()-1;j++){
                        String[] splitI = list.get(i).getShowId().split("-");
                        String intI = splitI[1].substring(1);
                        String[] splitJ = list.get(j).getShowId().split("-");
                        String intJ = splitJ[1].substring(1);
                        if(Integer.parseInt(intI)<Integer.parseInt(intJ)){
                            Order r=list.get(i);
                            list.set(i, list.get(j));
                            list.set(j, r);
                        }
                    }
                }
            }
            OrderTimeListVO orderTimeListVO = new OrderTimeListVO();
            List<OrderListVO> orderListVOS = new ArrayList<>();
            orderTimeListVO.setTimeType(TimeTypeEnum.getByType(type).getTime());
            for(Order order:list){
                OrderListVO orderListVO = new OrderListVO();
                BeanUtils.copyProperties(order,orderListVO);
                Product product = productService.getById(order.getProductId());
                if (product ==null)
                    break;
                orderListVO.setProductName(product.getName());
                orderListVO.setStatus(order.getStatus().getStatus());
                orderListVO.setAmount(FoodAmountTypeEnum.getByType(order.getAmount()).getAmount());
                orderListVO.setTimeType(order.getTimeType().getTime());
                orderListVO.setIsPay(order.getIsPay().getStatus());
                orderListVO.setIsPack(order.getIsPack().getType());

                if(order.getLabel() != null){
                    List<ContainLabelListDO> label = JSON.parseArray(order.getLabel(), ContainLabelListDO.class);
                    ArrayList<String> labelStrings = new ArrayList<>();
                    for (ContainLabelListDO containLabelListDO : label) {
                        if(containLabelListDO.getIsAlone()){
                            Map<String, Boolean> chooses = containLabelListDO.getChooses();
                            for(String key:chooses.keySet()) {
                                if(chooses.get(key)){
                                    labelStrings.add(containLabelListDO.getName() + " : " +key);
                                }
                            }
                        }else {
                            String keys = "";
                            Map<String, Boolean> chooses = containLabelListDO.getChooses();
                            for(String key:chooses.keySet()) {
                                if(chooses.get(key)){
                                    keys = keys + " " +key;
                                }
                            }
                            labelStrings.add(containLabelListDO.getName() + " : " +keys);
                        }
                    }
                    orderListVO.setLabel(labelStrings);
                }
                orderListVOS.add(orderListVO);
            }
            orderTimeListVO.setOrderListVOS(orderListVOS);
            orderTimeListVOS.add(orderTimeListVO);
        }
        return orderTimeListVOS;
    }



    public List<OrderListVO> getTodayOrders() {
        ArrayList<OrderListVO> orderListVOS = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date zero = new Date(calendar.getTimeInMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 24);
        Date last = new Date(calendar.getTimeInMillis());
        List<Order> list = lambdaQuery().between(Order::getGmtCreate,zero,last).eq(Order::getIsPay,OrderTypeEnum.FINISH_ORDER).eq(Order::getStatus,0).list();
        for (Order order : list) {
            OrderListVO orderListVO = new OrderListVO();
            BeanUtils.copyProperties(order,orderListVO);
            Product product = productService.getById(order.getProductId());
            if (product ==null)
                break;
            orderListVO.setProductName(product.getName());
            orderListVO.setStatus(order.getStatus().getStatus());
            orderListVO.setAmount(FoodAmountTypeEnum.getByType(order.getAmount()).getAmount());
            orderListVO.setTimeType(order.getTimeType().getTime());
            orderListVO.setIsPay(order.getIsPay().getStatus());
            orderListVO.setIsPack(order.getIsPack().getType());

            if(order.getLabel() != null){
                List<ContainLabelListDO> label = JSON.parseArray(order.getLabel(), ContainLabelListDO.class);
                ArrayList<String> labelStrings = new ArrayList<>();
                for (ContainLabelListDO containLabelListDO : label) {
                    if(containLabelListDO.getIsAlone()){
                        Map<String, Boolean> chooses = containLabelListDO.getChooses();
                        for(String key:chooses.keySet()) {
                            if(chooses.get(key)){
                                labelStrings.add(containLabelListDO.getName() + " : " +key);
                            }
                        }
                    }else {
                        String keys = "";
                        Map<String, Boolean> chooses = containLabelListDO.getChooses();
                        for(String key:chooses.keySet()) {
                            if(chooses.get(key)){
                                keys = keys + " " +key;
                            }
                        }
                        labelStrings.add(containLabelListDO.getName() + " : " +keys);
                    }
                }
                orderListVO.setLabel(labelStrings);
            }
            orderListVOS.add(orderListVO);
        }
        return orderListVOS;
    }


    public boolean isExist(String orderId) {
        return getById(orderId) != null;
    }

    @Transactional(rollbackFor = Exception.class)
    public void end(String orderId) {
        Order order = new Order();
        order.setId(orderId);
        order.setStatus(OrderStatusEnum.COMPLETE);

        order.setEndDate(new Date());
        updateById(order);

        Order byId = getById(orderId);
        ProductInfoVO productInfoVO = productService.get(byId.getProductId());

        // 发送消息通知
        MessageUtils.sendCookingEndMessage(byId.getUserId(),byId.getShowId().toString(), productInfoVO.getName(),"请到知食青年窗口取餐");
    }



    public List<OrderListVO> getTodayEndOrders() {
        ArrayList<OrderListVO> orderListVOS = new ArrayList<>();
        List<Order> list = lambdaQuery().eq(Order::getIsPay,OrderTypeEnum.FINISH_ORDER).eq(Order::getStatus, 4).or().eq(Order::getStatus, 5).list();
        for (Order order : list) {
            OrderListVO orderListVO = new OrderListVO();
            orderListVO.setId(order.getId());
            ProductInfoVO productInfoVO = productService.get(order.getProductId());
            if (productInfoVO ==null)
                break;
            orderListVO.setProductName(productInfoVO.getName());
            orderListVO.setShowId(order.getShowId());
            orderListVOS.add(orderListVO);
        }
        return orderListVOS;
    }
}
